﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MetroFramework.Forms;
using AForge.Imaging;
using AForge;
using AForge.Video;
using AForge.Video.DirectShow;
using System.Collections;
using AForge.Imaging.Filters;

namespace SpeakHelp
{
    delegate void ShowPicture(Bitmap bitmap);
    public delegate void ChangeSize(int w,int h);
    delegate void ShowWrongMessage();
    public partial class Form1 : System.Windows.Forms.Form
    {
        private int _cameraID;
        private int _cameraResolution;
        ShowPicture deleshowmethod;
        ChangeSize deleChangeMainFrmMethod;
        ShowWrongMessage deleShowWrongMsg;
        //鼠标是否正在绘制矩形
        private bool _selecting;
        //鼠标绘制的矩形
        private Rectangle _selection;
        private void ChangeFormSize(int width, int height)
        {
            this.Width = width;
            this.Height = height;
            this.StartPosition = FormStartPosition.CenterScreen;

        }
        public Form1()
        {
            InitializeComponent();
           
        }
        private FilterInfoCollection captureDevice;
        private VideoCaptureDevice device;
        public List<string> devices = new List<string>();

        public int Angle { get; set; }
        public int CameraID { get; set; }
        public int CameraResolution { get; set; }

        /// <summary>
        /// 枚举相机
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            
            captureDevice = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            //添加所有的相机设备
            foreach (FilterInfo device in captureDevice)
            {
                devices.Add(device.Name);
            }
            Angle = 0;
            deleshowmethod = new ShowPicture(ShowImg);
            deleChangeMainFrmMethod = new ChangeSize(ChangeFormSize);
            deleShowWrongMsg = new ShowWrongMessage(ShowWrongMsg);
        }
        public void ChangeSizeForm()
        {
            this.Invoke(deleChangeMainFrmMethod,this.Width,this.Height);
        }
        /// <summary>
        /// 指定相机
        /// </summary>
        /// <param name="indexOfCameras"></param>
        public void SpecifyCamera(int indexOfCameras)
        {
            device = new VideoCaptureDevice(captureDevice[indexOfCameras].MonikerString);  
        }
        /// <summary>
        /// 配置相机分辨率
        /// </summary>
        public void ConfigCamera(ref ArrayList resolutionsizes)
        {
            resolutionsizes.RemoveRange(0,resolutionsizes.Count);
            //得到制定相机的分辨率
            for (int i = 0; i < device.VideoCapabilities.Length; i++)
            {
                string resolution_size = device.VideoCapabilities[i].FrameSize.ToString();
                resolutionsizes.Add(resolution_size);
            }
        }
        public void SpecifyCameraResolution(int indexofcapabilities)
        {
            device.VideoResolution = device.VideoCapabilities[indexofcapabilities];
        }
        
        private void ShowImg(System.Drawing.Image bitmap)
        {
            this.pictureBox1.Image = bitmap;
        }
        private void FinalFrame_NewFrame(object sender, NewFrameEventArgs eventArgs)
        {
            //获得图像bitmap
            System.Drawing.Bitmap bmp = (System.Drawing.Bitmap)eventArgs.Frame.Clone(); 
            //旋转图片，得到bmpnew
            AForge.Imaging.Filters.RotateNearestNeighbor ro = new RotateNearestNeighbor(Angle);
            System.Drawing.Bitmap bmpnew =  ro.Apply(bmp);
            // Create cropped image:
            if (_selection.Width != 0 & _selecting == false)
            {
                try
                {
                    System.Drawing.Image img = bmpnew.Crop(_selection) as System.Drawing.Image;
                    // Fit image to the picturebox:
                    this.Invoke(deleshowmethod, img.Fit2PictureBox(pictureBox1));
                }
                catch (Exception)
                {
                    
                    this.Invoke(deleShowWrongMsg);
                    return;
                }
                finally
                {
                    

                }
                
            }
            else
            {
                this.Invoke(deleshowmethod, bmpnew);
            }

        }
        private void ShowWrongMsg()
        {
            Graphics g = Graphics.FromHwnd(this.pictureBox1.Handle);
            Brush bru = new System.Drawing.SolidBrush(Color.Red);
            g.DrawString("Do Not Change The Window Size", new Font("黑体", 14), bru, new PointF(0, 0));
        }
        private void 设置ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (device != null)
            {
                if (device.IsRunning)
                {
                    device.SignalToStop();
                    //device.WaitForStop();  // marking out that one solved it
                    device = null;
                    开始ToolStripMenuItem.Enabled = true;
                    停止ToolStripMenuItem.Enabled = false;
                }
            }
            this.Hide();
            Form2 frm = new Form2(this);
            frm.ShowDialog();
        }

        private void 开始ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            开始ToolStripMenuItem.Enabled = false;
            停止ToolStripMenuItem.Enabled = true;
            try
            {
                SpecifyCamera(this.CameraID);
                SpecifyCameraResolution(this.CameraResolution);
                device.NewFrame += new NewFrameEventHandler(FinalFrame_NewFrame);
                if (device.IsRunning)
                {
                    return;
                }
                else
                {
                    device.Start();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("请先设置好相机"+ex.Message);
            }
            
        }

        private void 停止ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            停止ToolStripMenuItem.Enabled = false;
            开始ToolStripMenuItem.Enabled = true;
                device.SignalToStop();
               // device.WaitForStop();  // marking out that one solved it
                device.NewFrame -= new NewFrameEventHandler(FinalFrame_NewFrame); // as sugested
                device = null;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (device == null)
            {
                return;
            }
            if (device.IsRunning)
            {
                device.SignalToStop();
                //device.WaitForStop();  // marking out that one solved it
                device.NewFrame -= new NewFrameEventHandler(FinalFrame_NewFrame); // as sugested
                device = null;                
            }
        }

        private int _angle;
        private void 旋转ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (Angle < 360)
            {
                Angle += 90;
            }
            else
            {
                Angle = 0;
            }
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            // Starting point of the selection:
            if (e.Button == MouseButtons.Left)
            {
                _selecting = true;
                _selection = new Rectangle(new System.Drawing.Point(e.X, e.Y), new Size());
            }
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            // Update the actual size of the selection:
            if (_selecting)
            {
                _selection.Width = Math.Abs(e.X - _selection.X);
                _selection.Height =Math.Abs(e.Y - _selection.Y);

                // Redraw the picturebox:
                pictureBox1.Refresh();
            }
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && _selecting)
            {              
                _selecting = false;
            }
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            if (_selecting)
            {
                // Draw a rectangle displaying the current selection
                Pen pen = Pens.GreenYellow;
                e.Graphics.DrawRectangle(pen, _selection);
            }
        }

    }
}
